package com.wxzz.elearing.comment.service.impl;

import cn.hutool.db.sql.Direction;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.wxzz.elearing.comment.amqp.producer.CommentProducer;
import com.wxzz.elearing.comment.api.app.WxQuestionsAnswersListController;
import com.wxzz.elearing.comment.dto.AnswersDescDto;
import com.wxzz.elearing.comment.dto.AnswersDto;
import com.wxzz.elearing.comment.dto.OrderIdDto;
import com.wxzz.elearing.comment.dto.QuestionsAnswersDto;
import com.wxzz.elearing.comment.entity.Comment;
import com.wxzz.elearing.comment.entity.CommunityQuestionsAnswersList;
import com.wxzz.elearing.comment.entity.QueAnsAcceptInfo;
import com.wxzz.elearing.comment.entity.QuestionsAnswersList;
import com.wxzz.elearing.comment.mapper.BannedMapper;
import com.wxzz.elearing.comment.mapper.CommentMapper;
import com.wxzz.elearing.comment.mapper.QueAnsAcceptInfoMapper;
import com.wxzz.elearing.comment.mapper.QuestionsAnswersListMapper;
import com.wxzz.elearing.comment.service.ICommentService;
import com.wxzz.elearing.comment.service.IQuestionsAnswersListService;
import com.wxzz.elearing.comment.service.openfeign.IWxPayFeign;
import com.wxzz.elearing.comment.service.openfeign.IWxUserApiFeign;
import com.wxzz.elearing.comment.vo.AnswersVo;
import com.wxzz.elearing.comment.vo.QuestionsContentDescVo;
import com.wxzz.elearning.common.dto.FeignWxUserDto;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

import static com.wxzz.elearing.comment.service.impl.GiveLikeServiceImpl.GIVELIKECOUNT;
import static com.wxzz.elearing.comment.service.impl.GiveLikeServiceImpl.HEATCOUNT;

@Service
public class CommentServiceImpl implements ICommentService {


    @Autowired
    public MongoTemplate mongoTemplate;

    @Resource
    private QuestionsAnswersListMapper questionsAnswersListMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CommentProducer commentProducer;

    @Resource
    private BannedMapper bannedMapper;

    @Override
    public ReturnVO saveComment(Comment comment) {
        //查询用户是否被封禁
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("user_id",comment.getWxUserId());
        queryWrapper.eq("module_type",0);
        Integer integer = bannedMapper.selectCount(queryWrapper);
        if(integer>0){
            throw new ServiceException("您已被禁止发言");
        }

        comment.setCreateTime(LocalDateTime.now());
        Comment insert = mongoTemplate.insert(comment);

        QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectById(comment.getArticleId());
        Optional.ofNullable(questionsAnswersList).ifPresent(e -> {
            //todo 小程序订阅
            SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
            systemMessageMqDto.setMessageDetail("您发布的问答:"+questionsAnswersList.getPublishContent()+"收到了评论信息");
            systemMessageMqDto.setMessageTitle("问答");
            systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
                {
                    add(e.getPublishPersonId());
                }
            });
            commentProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        });
        return new ReturnVO("评论成功", insert.getUid());
    }

    @Autowired
    private IWxUserApiFeign iWxUserApiFeign;
    @Override
    public ReturnVO<QuestionsContentDescVo> listAllComment(Long articleId) {
        Map<String, String> map = redisTemplate.opsForHash().entries(HEATCOUNT);
        String heatCount = articleId + ":heat";
        if (map.size() != 0) {
            String s = map.get(heatCount);
            if (StringUtil.isNotBlank(s)) {
                int i = Integer.parseInt(s);
                i += 1;
                redisTemplate.opsForHash().put(HEATCOUNT, heatCount, String.valueOf(i));
            } else {
                redisTemplate.opsForHash().put(HEATCOUNT, heatCount, "1");
            }
        } else {
            redisTemplate.opsForHash().put(HEATCOUNT, heatCount, "1");
        }
        QuestionsContentDescVo questionsContentDescVo = new QuestionsContentDescVo();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", articleId);
        QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectOne(queryWrapper);
        String publishImageUrl = questionsAnswersList.getPublishImageUrl();
//            String s = JSONObject.toJSONString(publishImageUrl);
        List<String> list = JSONObject.parseObject(publishImageUrl, List.class);
        questionsAnswersList.setPublishImageUrlList(list);

        BeanUtils.copyProperties(questionsAnswersList, questionsContentDescVo);

        FeignWxUserDto feignWxUserDto = iWxUserApiFeign.selectFeignWxUserDtoByWxUserId(questionsAnswersList.getPublishPersonId());
        questionsAnswersList.setIcon(feignWxUserDto.getIcon());
        questionsAnswersList.setPublishPerson(feignWxUserDto.getNickname());

        String artCount = articleId + ":count";
        //获取评论数量
        Query query = new Query();
        query.addCriteria(Criteria.where("articleId").is(articleId));
        questionsContentDescVo.setAnswersCount(mongoTemplate.count(query, "commentCollection"));

        //获取点赞数量
        Map<String, String> map1 = redisTemplate.opsForHash().entries(GIVELIKECOUNT);
        String str = map1.get(artCount);
        if (StringUtil.isNotBlank(str)) {
            int i = Integer.parseInt(str);
            questionsContentDescVo.setGiveLikeCount(i);
        } else {
            questionsContentDescVo.setGiveLikeCount(0);
        }
        //获取热度
        Map<String, String> map2 = redisTemplate.opsForHash().entries(HEATCOUNT);
        String num = map2.get(heatCount);
        if (StringUtil.isNotBlank(num)) {
            int i = Integer.parseInt(num);
            questionsContentDescVo.setHeatCount(i);
        } else {
            questionsContentDescVo.setHeatCount(0);
        }

        return new ReturnVO("评论查询成功,采纳已置顶", questionsContentDescVo);

    }

    @Resource
    private QueAnsAcceptInfoMapper queAnsAcceptInfoMapper;
    @Autowired
    private IWxPayFeign iWxPayFeign;


    @Transactional
    @Override
    public ReturnVO setAccept(QuestionsAnswersDto questionsAnswersDto) {

        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", questionsAnswersDto.getId());
        QuestionsAnswersList result = questionsAnswersListMapper.selectOne(queryWrapper);
        //查询评论的评论人员id
        Comment comment = mongoTemplate.findById(questionsAnswersDto.getUid(), Comment.class);

        if(result.getPublishPersonId().equals(comment.getWxUserId())){
            throw new ServiceException("无法采纳自己的评论");
        }
        if (result.getIsAccept() != 0) {
            ReturnVO returnVO = new ReturnVO();
            returnVO.setCode("500");
            returnVO.setMessage("该问题已采纳了其他答案!");
            return returnVO;
        }
        //修改文章评论被采纳信息
        questionsAnswersListMapper.setAccept(questionsAnswersDto);

        //查询刚才被采纳的信息插入采纳表
        QueAnsAcceptInfo queAnsAcceptInfo = new QueAnsAcceptInfo();
        queAnsAcceptInfo.setArticleId(questionsAnswersDto.getId());
        queAnsAcceptInfo.setAcceptId(questionsAnswersDto.getUid());

        queAnsAcceptInfo.setAcceptUserId(comment.getWxUserId());
        //查询文章id插入赏金
        QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectById(questionsAnswersDto.getId());
        queAnsAcceptInfo.setMoneyReward(questionsAnswersList.getMoneyReward());
        queAnsAcceptInfo.setCreateTime(LocalDateTime.now());
        queAnsAcceptInfoMapper.insert(queAnsAcceptInfo);
        if (result.getOrderId() != null&&result.getOrderId() != 0) {
            iWxPayFeign.giveAnswers(comment.getWxUserId(), result.getOrderId());
        }
        //todo 小程序订阅
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail("您的评论"+comment.getCommentContent()+"已被采纳");
        systemMessageMqDto.setMessageTitle("问答");
        systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
            {
                add(comment.getWxUserId());
            }
        });
        commentProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("采纳成功", null);
    }

    public ReturnVO<JgPageVo<List<Comment>>> answersDescList(AnswersDescDto answersDescDto) {
//        PageHelper.startPage(answersDescDto.getCurPage(), answersDescDto.getMaxPage());
        List<Comment> list = new ArrayList();
        QuestionsContentDescVo questionsContentDescVo = new QuestionsContentDescVo();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("id", answersDescDto.getId());
        QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectOne(queryWrapper);

        Integer isAccept = questionsAnswersList.getIsAccept();
        if (isAccept != 0) {
            Query query1 = new Query();
            String acceptId = questionsAnswersList.getAcceptId();
            if(StringUtils.isNotBlank(answersDescDto.getCommentContent())){
                Pattern pattern = Pattern.compile("^.*"+answersDescDto.getCommentContent()+".*$", Pattern.CASE_INSENSITIVE);
                query1.addCriteria(Criteria.where("commentContent").regex(pattern));
            }
            //query1.addCriteria(Criteria.where("_id").is(acceptId));
            query1.addCriteria(Criteria.where("uid").is(acceptId));//todo 这行报错暂时修改
            List<Comment> comment = mongoTemplate.find(query1, Comment.class);
            query1.with(new Sort(Sort.Direction.DESC, "createTime")).with(new PageRequest(answersDescDto.getCurPage() - 1, answersDescDto.getMaxPage()));
            query1.addCriteria(Criteria.where("articleId").is(answersDescDto.getId())).addCriteria(Criteria.where("_id").ne(acceptId));
            Query queryCount = new Query();
            queryCount.addCriteria(Criteria.where("articleId").is(answersDescDto.getId()));
            if(StringUtils.isNotBlank(answersDescDto.getCommentContent())){
                Pattern pattern = Pattern.compile("^.*"+answersDescDto.getCommentContent()+".*$", Pattern.CASE_INSENSITIVE);
                queryCount.addCriteria(Criteria.where("commentContent").regex(pattern));
            }
            long count = mongoTemplate.count(queryCount, "commentCollection");
            list = mongoTemplate.find(query1, Comment.class);
            list.forEach(model->{
                FeignWxUserDto feignWxUserDto = iWxUserApiFeign.selectFeignWxUserDtoByWxUserId(model.getWxUserId());
                model.setIcon(feignWxUserDto.getIcon());
                model.setNickname(feignWxUserDto.getNickname());
            });
            if (answersDescDto.getCurPage() == 1&&comment.size()>0) {
                list.add(0, comment.get(0));
                if (list.size() != 1 && list.size() > 9) {
                    list.remove(list.size() - 1);
                }
            }
            JgPageVo jgPageVo = new JgPageVo<>(new PageInfo(list));
            jgPageVo.setCurIndex(answersDescDto.getCurPage());
            jgPageVo.setPageSize(answersDescDto.getMaxPage());
            jgPageVo.setPagesCount((int) Math.ceil(count * 1.0 / answersDescDto.getMaxPage()));
            jgPageVo.setData(list);
            jgPageVo.setCount(count);

            return new ReturnVO("评论查询成功,采纳已置顶", jgPageVo);
        }
        Query query2 = new Query();
        query2.with(new Sort(Sort.Direction.DESC, "createTime")).with(new PageRequest(answersDescDto.getCurPage() - 1, answersDescDto.getMaxPage()));
//        query2.with(new Sort(Sort.Direction.DESC,"createTime"));
        query2.addCriteria(Criteria.where("articleId").is(answersDescDto.getId()));

        if(StringUtils.isNotBlank(answersDescDto.getCommentContent())){
            Pattern pattern = Pattern.compile("^.*"+answersDescDto.getCommentContent()+".*$", Pattern.CASE_INSENSITIVE);
            query2.addCriteria(Criteria.where("commentContent").regex(pattern));
        }
        list = mongoTemplate.find(query2, Comment.class);

        Query queryCount = new Query();
        queryCount.addCriteria(Criteria.where("articleId").is(answersDescDto.getId()));
        if(StringUtils.isNotBlank(answersDescDto.getCommentContent())){
            Pattern pattern = Pattern.compile("^.*"+answersDescDto.getCommentContent()+".*$", Pattern.CASE_INSENSITIVE);
            queryCount.addCriteria(Criteria.where("commentContent").regex(pattern));
        }
        long count = mongoTemplate.count(queryCount, "commentCollection");
//        questionsContentDescVo.setCommentList(commentList);
        JgPageVo jgPageVo = new JgPageVo<>(new PageInfo(list));
        jgPageVo.setCurIndex(answersDescDto.getCurPage());
        jgPageVo.setPageSize(answersDescDto.getMaxPage());
        jgPageVo.setPagesCount((int) count / answersDescDto.getMaxPage());
        jgPageVo.setData(list);
        jgPageVo.setCount(count);
        return new ReturnVO("评论查询成功", jgPageVo);
    }

    public ReturnVO<JgPageVo<List<AnswersVo>>> getAnswersList(AnswersDto answersDto) {
        Long id = answersDto.getUid();
        Query query = new Query();
        query.addCriteria(Criteria.where("wxUserId").is(id));
        query.with(new Sort(Sort.Direction.DESC, "createTime")).with(new PageRequest(answersDto.getCurPage() - 1, answersDto.getMaxPage()));
        //分页查询用户id的评论列表
        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        ArrayList<AnswersVo> answersVoArrayList = new ArrayList();
        commentList.forEach((comment) -> {
            AnswersVo answersVo = new AnswersVo();
            BeanUtils.copyProperties(comment, answersVo);
            //根据评论的文章id获取文章内容
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("id", answersVo.getArticleId());
            QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectOne(queryWrapper);
            if (questionsAnswersList != null) {
                answersVo.setPublishContent(questionsAnswersList.getPublishContent());
            } else {
                answersVo.setPublishContent("");
            }
            //图片数量存储
            List<String> publishImageUrlList = answersVo.getPublishImageUrlList();
            if (publishImageUrlList != null) {
                answersVo.setUrlListSize(publishImageUrlList.size());
            } else {
                answersVo.setUrlListSize(0);
            }

            QueryWrapper acceptQ = new QueryWrapper();
            acceptQ.eq("accept_id", answersVo.getId());
            Integer isAccept = questionsAnswersListMapper.selectCount(acceptQ);
            answersVo.setIsAccept(isAccept);
            answersVoArrayList.add(answersVo);
        });

        Query queryCount = new Query();
        queryCount.addCriteria(Criteria.where("wxUserId").is(answersDto.getUid()));
        long count = mongoTemplate.count(queryCount, "commentCollection");
        JgPageVo jgPageVo = new JgPageVo<>(new PageInfo(answersVoArrayList));
        jgPageVo.setCurIndex(answersDto.getCurPage());
        jgPageVo.setPageSize(answersDto.getMaxPage());
        jgPageVo.setPagesCount((int) count / answersDto.getMaxPage());
        jgPageVo.setData(answersVoArrayList);
        jgPageVo.setCount(count);
        return new ReturnVO("评论查询成功", jgPageVo);
    }

    public ReturnVO getUserIdByOrderId(Long orderId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("order_id", orderId);
        QuestionsAnswersList questionsAnswersList = questionsAnswersListMapper.selectOne(queryWrapper);
        if (questionsAnswersList == null) {
            throw new ServiceException("没有查询到此订单id");
        }
        if (StringUtils.isBlank(questionsAnswersList.getAcceptId())) {
            throw new ServiceException("此文章没有采纳的评论,请先采纳!");
        }
        String acceptId = questionsAnswersList.getAcceptId();
        Comment comment = mongoTemplate.findById(acceptId, Comment.class);
        return new ReturnVO("查询成功", comment.getWxUserId());
    }



    public ReturnVO deleteComment(Comment comment) {
        Comment comment1 = mongoTemplate.findById(comment.getUid(), Comment.class);

        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(comment.getUid()));
        mongoTemplate.remove(query,Comment.class);

        //todo 小程序订阅
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail("很抱歉,您发布的评论:"+comment1.getCommentContent()+"因违规已被管理员删除，详情请在小程序内查看");
        systemMessageMqDto.setMessageTitle("问答");
        systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
            {
                add(comment1.getWxUserId());
            }
        });
        commentProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("问答评论删除成功", 1);
    }


    public ReturnVO deleteQueAns(QuestionsAnswersList questionsAnswersList) {

        QuestionsAnswersList questionsAnswersList1 = questionsAnswersListMapper.selectById(questionsAnswersList.getId());

        questionsAnswersListMapper.deleteById(questionsAnswersList.getId());
        //todo 小程序订阅
        SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
        systemMessageMqDto.setMessageDetail("很抱歉,您发布的文章:" + questionsAnswersList1.getPublishContent()+ " 因违规已被管理员删除，详情请在小程序内查看");
        systemMessageMqDto.setMessageTitle("问答");
        systemMessageMqDto.setWxUserIds(new ArrayList<Long>() {
            {
                add(questionsAnswersList1.getPublishPersonId());
            }
        });
        commentProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        return new ReturnVO("问答文章删除成功", 1);
    }
}
